#pragma once




/**
 * This is a simple class that can be used to cache data.
 * It can store a certain value and contains a flag that describes
 * if the data may be used or not (invalidated cache-data may not
 * be used by design).
 */
template <typename T>
class Cache
{
private:

	bool   m_valid;
	T      m_data;

public:

	/**
	 * Create a new empty cache.
	 */
	Cache()
		: m_valid(false)
	{}

	/**
	 * Create a new cache from the given data.
	 */
	Cache(const T& data)
		: m_valid(true)
		, m_data(data)
	{}



	/**
	 * Test if this cache is valid.
	 */
	bool isValid() const
	{
		return m_valid;
	}

	/**
	 * Test if this cache is invalid.
	 */
	bool isInvalid() const
	{
		return !m_valid;
	}

	/**
	 * Invalidate this cache.
	 * This means that the cache's data may not be used anymore
	 * and must be updated some time...
	 */
	void invalidate()
	{
		m_valid = false;
	}

	/**
	 * Update this cache with new data.
	 * This makes the cache valid again (if it was invalid before).
	 */
	void update(const T& newData)
	{
		m_data  = newData;
		validate();
	}

	/**
	 * Validate the cache again without changing the underlying
	 * data.
	 */
	void validate()
	{
		m_valid = true;
	}


	/**
	 * Access the data of this cache.
	 */
	T* operator->()
	{
		if(isInvalid())
			BOOSTEXT_THROW(programming_error("This cache is invalid and thus its data may not be accessed"));

		return &m_data;
	}

	/**
	 * Access the data of this cache.
	 */
	const T* operator->() const
	{
		if(isInvalid())
			BOOSTEXT_THROW(programming_error("This cache is invalid and thus its data may not be accessed"));

		return &m_data;
	}

	/**
	 * Access the data of this cache.
	 */
	T& operator*()
	{
		if(isInvalid())
			BOOSTEXT_THROW(programming_error("This cache is invalid and thus its data may not be accessed"));

		return m_data;
	}

	/**
	 * Access the data of this cache.
	 */
	const T& operator*() const
	{
		if(isInvalid())
			BOOSTEXT_THROW(programming_error("This cache is invalid and thus its data may not be accessed"));

		return m_data;
	}

	/**
	 * Access the data of this cache.
	 */
	T& get()
	{
		if(isInvalid())
			BOOSTEXT_THROW(programming_error("This cache is invalid and thus its data may not be accessed"));

		return m_data;
	}

	/**
	 * Access the data of this cache.
	 */
	const T& get() const
	{
		if(isInvalid())
			BOOSTEXT_THROW(programming_error("This cache is invalid and thus its data may not be accessed"));

		return m_data;
	}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
